package org.boot.thread.configurer;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

import static org.boot.thread.constant.ThreadConstant.*;

/**
 * spring-boot-thread 相关配置类
 * <p>
 * 注：如果存在多个线程池，且未指定使用哪个，则优先使用 {@link AsyncConfigurer#getAsyncExecutor()} 返回的线程池；否则将使用默认线程池
 *
 * @author 李坤
 * @date 2022/4/27 19:41
 */
@EnableAsync
@Configuration
public class ThreadPoolTaskExecutors implements AsyncConfigurer {

    private final ThreadPoolExecutor.CallerRunsPolicy callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();

    @Bean("noQueueCapacityExecutor")
    public ThreadPoolTaskExecutor noQueueCapacityExecutor() {
        // 线程使用顺序：核心线程 > 缓冲队列 > 最大线程数
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();

        // 缓冲队列
        taskExecutor.setQueueCapacity(0);
        // 最大线程数
        taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        // 核心线程数
        taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        // 线程空闲时间(超时后将销毁非核线程)
        taskExecutor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        // 线程拒绝策略(重试添加当前的任务直到成功)
        taskExecutor.setRejectedExecutionHandler(callerRunsPolicy);

        // 线程名称前缀
        taskExecutor.setThreadNamePrefix("no_queue_capacity-");

        return taskExecutor;
    }


    /*---------------------------------------Overrides method in AsyncConfigurer--------------------------------------*/


    @Override
    @Bean("defaultExecutor")
    public Executor getAsyncExecutor() {
        // 线程使用顺序：核心线程 > 缓冲队列 > 最大线程数
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();

        // 最大线程数
        taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        // 核心线程数
        taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        // 缓冲队列(执行缓冲任务的队列)
        taskExecutor.setQueueCapacity(QUEUE_CAPACITY);
        // 线程空闲时间(超时后将销毁非核线程)
        taskExecutor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        // 线程拒绝策略(重试添加当前的任务直到成功)
        taskExecutor.setRejectedExecutionHandler(callerRunsPolicy);

        // 线程名称前缀
        taskExecutor.setThreadNamePrefix(THREAD_NAME_PREFIX);

        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }

}
